﻿using Authentication.Core.Configuration;
using Authentication.Model.Interface;
using Authentication.Model.Model;
using Common.Contract;
using Common.Contract.Authentication.Record;
using Common.Contract.Authentication.Request;
using Common.Data.Repository.Enum;
using Common.Service.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Authentication.Core.ServiceCommand
{
    public class UpdateChangeDaoRequestByCifAndProductServiceCommand : ProviderServiceCommand<IProviderFactory, UpdateChangeDaoRequestRequest, ResponseRecord>
    {
        public UpdateChangeDaoRequestByCifAndProductServiceCommand(IProviderFactory providers) : base(providers) { }
        #region Private Properties
        private UserRecord currentUser;
        #endregion
        protected override void Validate(UpdateChangeDaoRequestRequest request)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (!request.Header.ApplicationKey.HasValue || request.Header.ApplicationKey == Guid.Empty)
            {
                throw new ArgumentException("ApplicationKey must be set", "request");
            }
            if (request.CurrentUser == null)
            {
                throw new ArgumentException("User record must be set", "request");
            }
            else
            {
                currentUser = request.CurrentUser;
            }
            if (request.Record == null || request.Record.Id == 0)
            {
                throw new ArgumentException("Record must be set", "request");
            }
            if (request.ListChangeDaoCif == null)
            {
                throw new ArgumentException("ListChangeDaoCif must be set", "request");
            }
            if (request.ListChangeDaoProduct == null)
            {
                throw new ArgumentException("ListChangeDaoProduct must be set", "request");
            }
        }

        protected override bool OnExecute(ResponseRecord response)
        {
            var record = Request.Record;
            var listChangeDaoCif = Request.ListChangeDaoCif;
            var listProduct = Request.ListChangeDaoProduct;
            List<ChangeDaoCif> listChangeDaoCifUpdate = new List<ChangeDaoCif>();
            List<ChangeDaoProductChecked> listChangeDaoProductUpdate = new List<ChangeDaoProductChecked>();
            bool savedUser = false;
            try
            {
                var checkRequest = Providers.ChangeDao.RetrieveChangeDaoRequestByIdAndItem(record.Id, listChangeDaoCif, listProduct);
                if (checkRequest != null && checkRequest.Id != 0)
                {
                    var oldStatus = checkRequest.Status;
                    switch (currentUser.GroupIdentifier)
                    {
                        case "1":
                            checkRequest.Status = (int)StatusChangeDaoEnum.HOApproved;
                            checkRequest.IsDeviation = record.IsDeviation ? 1 : 0;
                            listChangeDaoCifUpdate = listChangeDaoCif.Select(x => new ChangeDaoCif
                            {
                                Id = x.Id,
                                Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            listChangeDaoProductUpdate = listProduct.Select(x => new ChangeDaoProductChecked
                            {
                                Id = x.Id,
                                Status = x.NeedApprove ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            break;
                        case "2":
                            if (SystemConfiguration.UserMBDApprovedDao.Contains(currentUser.UserName))
                            {
                                checkRequest.Status = (int)StatusChangeDaoEnum.HOApproved;
                            }
                            else
                            {
                                checkRequest.Status = (int)StatusChangeDaoEnum.BranchApproved;
                            };
                            checkRequest.IsDeviation = record.IsDeviation ? 1 : 0;
                            listChangeDaoCifUpdate = listChangeDaoCif.Select(x => new ChangeDaoCif
                            {
                                Id = x.Id,
                                Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            listChangeDaoProductUpdate = listProduct.Select(x => new ChangeDaoProductChecked
                            {
                                Id = x.Id,
                                Status = x.NeedApprove ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            break;
                        case "3":
                            if (SystemConfiguration.PostionHeadBranch.ToLower().Contains(currentUser.Position.ToLower()))
                            {
                                checkRequest.Status = (int)StatusChangeDaoEnum.BranchApproved;
                            }
                            else
                            {
                                checkRequest.Status = (int)StatusChangeDaoEnum.Request;
                            }
                            checkRequest.IsDeviation = record.IsDeviation ? 1 : 0;
                            listChangeDaoCifUpdate = listChangeDaoCif.Select(x => new ChangeDaoCif
                            {
                                Id = x.Id,
                                Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            listChangeDaoProductUpdate = listProduct.Select(x => new ChangeDaoProductChecked
                            {
                                Id = x.Id,
                                Status = x.NeedApprove ? (int)StatusChangeDaoCifEnum.Aproved : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            break;
                        case "4":
                            checkRequest.Status = (int)StatusChangeDaoEnum.Request;
                            listChangeDaoCifUpdate = listChangeDaoCif.Select(x => new ChangeDaoCif
                            {
                                Id = x.Id,
                                Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Request : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            listChangeDaoProductUpdate = listProduct.Select(x => new ChangeDaoProductChecked
                            {
                                Id = x.Id,
                                Status = x.NeedApprove ? (int)StatusChangeDaoCifEnum.Request : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            break;
                        case "6":
                            checkRequest.Status = (int)StatusChangeDaoEnum.Request;
                            listChangeDaoCifUpdate = listChangeDaoCif.Select(x => new ChangeDaoCif
                            {
                                Id = x.Id,
                                Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Request : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            listChangeDaoProductUpdate = listProduct.Select(x => new ChangeDaoProductChecked
                            {
                                Id = x.Id,
                                Status = x.NeedApprove ? (int)StatusChangeDaoCifEnum.Request : (int)StatusChangeDaoCifEnum.Reject
                            }).ToList();
                            break;
                        default:
                            break;
                    }
                    bool isSaveChangeDao = Providers.ChangeDao.UpdateStatusChangeDaoRequest(checkRequest);
                    if (isSaveChangeDao)
                    {
                        savedUser = Providers.ChangeDao.UpdateChangeDaoCif(listChangeDaoCifUpdate) && Providers.ChangeDao.UpdateChangeDaoProduct(listChangeDaoProductUpdate);
                        if (!savedUser)
                        {
                            checkRequest.Status = oldStatus;
                            Providers.ChangeDao.UpdateStatusChangeDaoRequest(checkRequest);
                            response.ErrorMessage = string.Format("Có lỗi xảy ra với request {0}, vui lòng thử lại", record.Id.ToString());
                            savedUser = false;
                        }
                    }
                    else
                    {
                        response.ErrorMessage = string.Format("Có lỗi xảy ra với request {0}, vui lòng thử lại", record.Id.ToString());
                        savedUser = false;
                    }
                }
                else
                {
                    response.ErrorMessage = string.Format("Không tồn tại request {0} trên hệ thống", record.Id.ToString());
                    savedUser = false;
                }
            }
            catch (Exception ex)
            {
                response.ErrorMessage = ex.Message;
                savedUser = false;
            }
            return savedUser;
        }
    }
}
